package com.axungu;

import com.axungu.common.Result;
import com.axungu.exception.NoFoundException;
import com.axungu.exception.NoLoginException;
import com.axungu.exception.NotSufficientFundsException;
import com.axungu.exception.PermissionDeniedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Objects;
import java.util.Set;

@Slf4j
@RestController
@ControllerAdvice
@RequestMapping("${server.error.path:${error.path:/error}}")
public class FundaErrorController implements ErrorController {


    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping
    public Result doHandleError() {
        return Result.instance(Result.Code.NO_FOUND, "对不起，您访问的页面不存在");
    }

    /**
     * 校验错误拦截处理
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result methodArgumentNotValidException(MethodArgumentNotValidException exception) {

        BindingResult result = exception.getBindingResult();
        String message = "请填写正确信息";
        if (result.hasErrors()) {
            message = Objects.requireNonNull(result.getFieldError()).getDefaultMessage();
        }
        return Result.instance(message);
    }

    @ExceptionHandler(ConstraintViolationException.class)
    public Result constraintViolationException(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        return Result.instance(Result.Code.SERVER_ERROR, constraintViolations.iterator().next().getMessageTemplate());
    }

    @ExceptionHandler(NoFoundException.class)
    public Result noFoundException(Exception ex) {
        return Result.instance(Result.Code.NO_FOUND, "您访问的内容不存在");
    }

    @ExceptionHandler(PermissionDeniedException.class)
    public Result permissionDeniedException(Exception ex) {
        return Result.instance(Result.Code.FORBIDDEN, "您没有权限访问此内容");
    }

    @ExceptionHandler(NoLoginException.class)
    public Result noLoginException(Exception ex) {
        return Result.instance(Result.Code.NO_LOGIN, "您还没有登录，请先登录");
    }

    @ExceptionHandler(NotSufficientFundsException.class)
    public Result notSufficientFundsException(Exception ex) {
        return Result.instance(Result.Code.NOT_SUFFICIENT_FUNDS, "您账户全额不足，请先充值");
    }

    @ExceptionHandler(BindException.class)
    public Result handleBindException(BindException ex) {
        BindingResult result = ex.getBindingResult();
        String message = "请填写正确信息";
        if (result.hasErrors()) {
            message = Objects.requireNonNull(result.getFieldError()).getDefaultMessage();
        }
        return Result.instance(message);
    }

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception ex) {
        log.error("system error", ex);
        return Result.instance(Result.Code.SERVER_ERROR, "系统忙，请稍后再试");
    }
}
